package com.netrica.truco;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;

import com.netrica.truco.utils.Card;
import com.netrica.truco.utils.Deck;
import com.netrica.truco.utils.Regra;
import com.netrica.truco.vo.Jogador;
import com.netrica.truco.vo.Mesa;


import flex.messaging.MessageBroker;
import flex.messaging.messages.AbstractMessage;
import flex.messaging.messages.AsyncMessage;
import flex.messaging.util.UUIDUtils;

public class Game {
	
	private MessageBroker msgBroker;
    private AsyncMessage msg;
    private AsyncMessage msg2;
    private ArrayList<Mesa> mesas=new ArrayList<Mesa>();
    private ArrayList<Mesa> mesasWait=new ArrayList<Mesa>();
    private int mesaId=1;
    private static final String TRUCADA = "trucada";
	public Game(){
		String clientID = UUIDUtils.createUUID(false);
		msgBroker= MessageBroker.getMessageBroker(null);
        msg= new AsyncMessage();
        msg.setDestination("dataTime");
        msg.setClientId(clientID);
        msg.setMessageId(UUIDUtils.createUUID(false));
        msg.setTimestamp(System.currentTimeMillis());
        
        String clientID2 = UUIDUtils.createUUID(false);
        msg2= new AsyncMessage();
        msg2.setDestination("chat");
        msg2.setClientId(clientID2);
        msg2.setMessageId(UUIDUtils.createUUID(false));
        msg2.setTimestamp(System.currentTimeMillis());
	}
	
	
	public Jogador createMesa(int id, int idMesa, Jogador jogador){
		//Jogador jogador=new Jogador();
		jogador.setId(id);
		Mesa mesa;
		if(idMesa==0)
		{
			mesa=new Mesa();
			Deck baralho=new Deck();
			baralho.shuffle();
			mesa.setBaralho(baralho);
			mesa.setNumero(mesaId++);
			mesa.setNome(jogador.getMesa());
			jogador.setNumeroMesa(mesa.getNumero());
			jogador.setMao(getHand(mesa.getBaralho()));
			mesa.getDupla().add(jogador);
			mesasWait.add(mesa);
			mesaMessageUpdate(mesa);
		}
		else
		{
			mesa=getMesaAguardando(idMesa);
			if(mesa.getDupla().size()>0)
			{
				jogador.setNumeroMesa(mesa.getNumero());
				jogador.setMao(getHand(mesa.getBaralho()));
				mesa.getDupla().add(jogador);
				startMesa(mesa);//iniciar a partida (front verifica a mesa e inicia o cronometro, enviar iddamesa e id jo jogador q inicia)
				mesas.add(mesa);
				mesasWait.remove(mesa);
				mesaMessageUpdate(mesa);
			}
		}
		
		/*versão 1.0;
			 * jogador.setNumeroMesa(mesa.getNumero());
			jogador.setMao(getHand(mesa.getBaralho()));
			mesa.getDupla().add(jogador);
			startMesa(mesa);//iniciar a partida (front verifica a mesa e inicia o cronometro, enviar iddamesa e id jo jogador q inicia)
			mesas.add(mesa);
			mesa=new Mesa();*/			
		
		return jogador;
	}
	
	public ArrayList getMesasWait()
	{
		ArrayList mesasAguardando=new ArrayList();
		for (Mesa table : mesasWait) {
			HashMap mesa = new HashMap();
			mesa.put("mesa",table.getNumero() );
			mesa.put("mesaNome",table.getNome());
			mesa.put("idUserWait", table.getDupla().get(0));
			mesasAguardando.add(mesa);
		}
		return mesasAguardando;
	}
	
	public void removeMesaWait(int idMesa)
	{
		Mesa mesa=getMesa(idMesa);
		if(mesa!=null)
		{
			if(mesas.contains(mesa) && mesa.getDupla().size()>1)
			{
				
				mesas.remove(mesa);
				abandonouMesa(idMesa);
				
			}
			else
			{
				mesa=getMesaAguardando(idMesa);
				if(mesasWait.contains(mesa))
				{
					mesasWait.remove(mesa);
					mesaMessageUpdate(mesa);
				}
			}
		}
	}
	
	private void mesaMessageUpdate(Mesa mesa)
	{
		ArrayList mesasEsperando=getMesasWait();
		HashMap body = new HashMap();
		body.put("type","updateMesas");
        body.put("mesa", mesa.getNumero());
        body.put("mesaNome", mesa.getNumero());
        body.put("listMesasWait", mesasEsperando);
        msg2.setBody(body);
        msgBroker.routeMessageToService(msg2, null);
	}
	private void abandonouMesa(int idMesa)
	{
		HashMap body = new HashMap();
		body.put("type","abandonouMesa");
        body.put("mesa", idMesa);
        msg2.setBody(body);
        msgBroker.routeMessageToService(msg2, null);
	}
	
	public void jogada(String carta,int NMesa, int NJogador){
		for (Mesa table : mesas) {
			if(table.getNumero()==NMesa)
			{
				verificaRodada(table,carta,NJogador);
			}
		}
		
		
	}
	private void verificaRodada(Mesa mesa,String carta,int NJogador)
	{
		Card card=Card.toCard(carta);
		mesa.setNRodada(mesa.getNRodada()+1);
		Regra regra = new Regra();
		int posJogador=mesa.getPosJogadorAnterior()==0?1:0;
		int idGanhador=0;
		switch (mesa.getNRodada()) {
		case 1:
			mesa.setValorCartaAnterior(regra.getValueCard(card,Card.toCard(mesa.getVira())));
			proximaJogada(mesa, mesa.getDupla().get(posJogador).getId(), NJogador, carta,0,0);
			break;
		case 2:
			int cartaAtual=regra.getValueCard(card,Card.toCard(mesa.getVira()));
			if(mesa.getValorCartaAnterior()>cartaAtual)
			{
				posJogador=mesa.getPosJogadorAnterior();
			}
			mesa.setFPrimeira(mesa.getDupla().get(posJogador).getId());
			mesa.setPosJogadorAnterior(posJogador);
			if(mesa.getValorCartaAnterior()==cartaAtual)
			{
				mesa.setFPrimeira(0);
			}
			proximaJogada(mesa, mesa.getDupla().get(posJogador).getId(), NJogador, carta,mesa.getFPrimeira(),0);
			break;
		case 3:
			mesa.setValorCartaAnterior(regra.getValueCard(card,Card.toCard(mesa.getVira())));
			proximaJogada(mesa, mesa.getDupla().get(posJogador).getId(), NJogador, carta,0,0);
			break;
		case 4:
			if(mesa.getValorCartaAnterior()>regra.getValueCard(card,Card.toCard(mesa.getVira())))
			{
				posJogador=mesa.getPosJogadorAnterior();
			}
			
			mesa.setFSegunda(mesa.getDupla().get(posJogador).getId());
			mesa.setPosJogadorAnterior(posJogador);
			
			if(mesa.getValorCartaAnterior()==regra.getValueCard(card,Card.toCard(mesa.getVira())))
			{
				mesa.setFSegunda(0);
			}
			
			
			if(mesa.getFPrimeira()!=0 && mesa.getFPrimeira()==mesa.getFSegunda())
			{
				idGanhador=mesa.getFSegunda();
			}
			else if(mesa.getFSegunda()==0)
			{
				if(mesa.getFPrimeira()!=0)
					idGanhador=mesa.getFPrimeira();
			}
			else if(mesa.getFPrimeira()==0)
			{
				if(mesa.getFSegunda()!=0)
					idGanhador=mesa.getFSegunda();
			}
			proximaJogada(mesa, mesa.getDupla().get(posJogador).getId(), NJogador, carta, mesa.getFSegunda(),idGanhador);
			break;
		case 5:
			mesa.setValorCartaAnterior(regra.getValueCard(card,Card.toCard(mesa.getVira())));
			proximaJogada(mesa, mesa.getDupla().get(posJogador).getId(),  NJogador, carta,0,0);
			break;
		case 6:
			int vcartaAtual=regra.getValueCard(card,Card.toCard(mesa.getVira()));
			if(mesa.getValorCartaAnterior()>vcartaAtual)
			{
				posJogador=mesa.getPosJogadorAnterior();
			}
			mesa.setPosJogadorAnterior(posJogador);
			mesa.setFTerceira(mesa.getDupla().get(posJogador).getId());
			
			if(mesa.getValorCartaAnterior()==vcartaAtual)
			{
				mesa.setFTerceira(0);
			}
			
			if(mesa.getFPrimeira()==mesa.getFSegunda()||mesa.getFPrimeira()==mesa.getFTerceira())
			{
				idGanhador=mesa.getFPrimeira();
			}
			if(mesa.getFSegunda()==mesa.getFPrimeira()||mesa.getFSegunda()==mesa.getFTerceira())
			{
				idGanhador=mesa.getFSegunda();
			}
			if(mesa.getFTerceira()==mesa.getFSegunda()||mesa.getFPrimeira()==mesa.getFTerceira())
			{
				idGanhador=mesa.getFTerceira();
			}
			if(mesa.getFPrimeira()==0&&mesa.getFSegunda()==0)
			{
				if(mesa.getFTerceira()!=0)
				{
					idGanhador=mesa.getFTerceira();
				}
				else
				{
					//comparar os naipes
				}
			}
			else if(mesa.getFTerceira()==0)
			{
				idGanhador=mesa.getFPrimeira();
			}
			
			proximaJogada(mesa, mesa.getDupla().get(posJogador).getId(), NJogador, carta,mesa.getFTerceira(),idGanhador);
			break;

		default:
			break;
		}

	}
	private void proximaJogada(Mesa mesa,int usuarioVez ,int iduserJogada,String cartaRodada,int winHand, int winGame)
	{
		HashMap body = new HashMap();
		body.put("rodada",mesa.getNRodada() );
        body.put("mesa", mesa.getNumero());
        body.put("usuarioVez", usuarioVez);
        body.put("iduserJogada", iduserJogada);
        body.put("cartaJogada", cartaRodada);
        body.put("fezMao", winHand);//ganhou o turno
        body.put("venceuRodada", winGame);//ganhou a rodada
        msg.setBody(body);
        msgBroker.routeMessageToService(msg, null);
        if(winGame>0)
        {
        	mesa.getBaralho().shuffle();
        }
	}
	
	public Jogador changeHand(int idmesa, int idJogador)
	{
		Jogador player = null;
		Mesa table=getMesa(idmesa);
		for (Jogador jogador : table.getDupla()) {
			if(jogador.getId()==idJogador)
			{
				player=jogador;
			}
		}
		player.setMao(getHand(table.getBaralho()));
		return player;
	}
	
	private Mesa getMesa(int idMesa)
	{
		Mesa mesa = new Mesa();
		for (Mesa table : mesas) {
			if(table.getNumero()==idMesa)
			{
				mesa=table;
			}
		}
		return mesa;
	}
	
	private Mesa getMesaAguardando(int idMesa)
	{
		Mesa mesa = new Mesa();
		for (Mesa table : mesasWait) {
			if(table.getNumero()==idMesa)
			{
				mesa=table;
			}
		}
		return mesa;
	}
	
	public HashMap getVira(int idMesa)
	{
		Mesa table=getMesa(idMesa);
		HashMap body = new HashMap();
		body.put("rodada",table.getNRodada());
        body.put("mesa", table.getNumero());
        body.put("usuarioVez", table.getDupla().get(table.getUserInicia()).getId());
        body.put("vira", table.getVira());
		return body;
	}
	
	public void resetTable(int idmesa,int inicia)
	{
		int posJogador=inicia;
		Mesa table=getMesa(idmesa);
		table.setPosJogadorAnterior(posJogador);
		table.setUserInicia(posJogador);
		startMesa(table);
	}
	
	private void startMesa(Mesa mesa){
		mesa.setVira(mesa.getBaralho().draw().toString());
		//mesa.setPosJogadorAnterior(0);
		mesa.setNRodada(0);
		Jogador jogador1=new Jogador();
		Jogador jogador2=new Jogador();
		jogador1.setId(mesa.getDupla().get(0).getId());
		jogador2.setId(mesa.getDupla().get(1).getId());
		jogador1.setNome(mesa.getDupla().get(0).getNome());
		jogador2.setNome(mesa.getDupla().get(1).getNome());
		jogador1.setAvatar(mesa.getDupla().get(0).getAvatar());
		jogador2.setAvatar(mesa.getDupla().get(1).getAvatar());
		jogador1.setDerrotas(mesa.getDupla().get(0).getDerrotas());
		jogador2.setDerrotas(mesa.getDupla().get(1).getDerrotas());
		jogador1.setPartidas(mesa.getDupla().get(0).getPartidas());
		jogador2.setPartidas(mesa.getDupla().get(1).getPartidas());
		jogador1.setVitorias(mesa.getDupla().get(0).getVitorias());
		jogador2.setVitorias(mesa.getDupla().get(1).getVitorias());
		
		HashMap body = new HashMap();
		body.put("rodada",mesa.getNRodada());
        body.put("mesa", mesa.getNumero());
        body.put("usuarioVez", mesa.getDupla().get(mesa.getUserInicia()).getId());
        body.put("vira", mesa.getVira());
        body.put("jogador1", jogador1);
        body.put("jogador2", jogador2);
        msg.setBody(body);
        msgBroker.routeMessageToService(msg, null);
	}
	
	private ArrayList getHand(Deck baralho){
		ArrayList cartas=new ArrayList();
		cartas.add(baralho.draw().toString());
		cartas.add(baralho.draw().toString());
		cartas.add(baralho.draw().toString());
		return cartas;
	}

}
